package com.zhan.ielts.web.filter;

import com.zhan.frame.core.web.domain.Result;
import com.zhan.ielts.domain.user.VisitLog;
import com.zhan.ielts.service.user.IVisitLogService;
import net.sf.json.JSONObject;
import org.springframework.util.StringUtils;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.context.support.XmlWebApplicationContext;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by tlfu on 2017/5/17.
 */
public class LoginFilter implements Filter {
    private IVisitLogService visitLogService;
    private final static ExecutorService service = Executors.newFixedThreadPool(5);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        ServletContext sc = filterConfig.getServletContext();
        XmlWebApplicationContext cxt = (XmlWebApplicationContext) WebApplicationContextUtils.getWebApplicationContext(sc);

        if (cxt != null && cxt.getBean("visitLogService") != null && visitLogService == null){
            visitLogService = (IVisitLogService) cxt.getBean("visitLogService");
        }
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;

        HttpSession session = req.getSession(true);

        //从session里取的用户名信息
        String username = (String) session.getAttribute("username");
        String url = req.getServletPath();
        //判断如果没有取到用户信息,就跳转到登陆页面
        if (!StringUtils.isEmpty(username) || url.contains("/user/login")) {
            if (!url.contains("/user/login") && visitLogService != null) {
                insertVisitLog(username, url);
            }
            filterChain.doFilter(request, response);
        } else if (StringUtils.isEmpty(username)) {
            if(!url.contains("resources")&& req.getMethod().equalsIgnoreCase("GET")&&!url.contains("favicon.ico")){
                Map parameters = req.getParameterMap();
                StringBuilder sb = new StringBuilder();
                if (parameters != null && parameters.size() > 0) {
                    for (Iterator iter = parameters.keySet().iterator(); iter.hasNext(); ) {
                        String key = (String) iter.next();
                        String[] values = (String[]) parameters.get(key);
                        StringBuilder value = new StringBuilder();
                        for (int i = 0; i < values.length; i++) {
                            value.append(values[i]).append(",");
                        }
                        if (value.toString().contains(",")) {
                            value.setLength(value.length() - 1);
                        }
                        if (sb.toString().contains("?")) {
                            sb.append("&" + key + "=" + value.toString());
                        } else {
                            sb.append("?" + key + "=" + value.toString());
                        }
                    }
                }
                if (sb.length() > 0) {
                    url = url + sb.toString();
                }
                session.setAttribute("url", getContextPath(req) + url);
            }
            String requestType =req.getHeader("X-Requested-With");
            if (requestType != null && requestType.equals("XMLHttpRequest")) {
                JSONObject data = new JSONObject();
                data.put(Result.Status.ERROR,"timeout");
                data.put("message","timeout,please login again");
                res.getWriter().write(data.toString());
            }else{
                String loginUrl = getContextPath(req) + "/user/login";
                res.sendRedirect(loginUrl);
            }
        }
    }

    private void insertVisitLog(final String userName, final String url) {
        service.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    VisitLog log = new VisitLog();
                    log.setUserName(userName);
                    log.setVisitUrl(url);
                    log.setCreateTime(new Date());
                    visitLogService.insert(log);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    private String getContextPath(HttpServletRequest request) {
        String root = "http://" + request.getHeader("Host");
        if (!StringUtils.isEmpty(request.getContextPath())) {
            root = root + request.getContextPath();
        }
        return root;
    }

    @Override
    public void destroy() {

    }
}
